home *** CD-ROM | disk | FTP | other *** search
- #ifndef _H_RTTI
- #define _H_RTTI
-
- /* %Z%%I% %G% %U% %W% */
- /*
- * COMPONENT_NAME: (COMINC) Common Header File for RTTI
- *
- * ORIGINS: 27
- *
- * (C) COPYRIGHT International Business Machines Corp. 1992
- * This work was supported by a grant from International Business
- * Machines, Inc. These procedures are contributed to the public domain
- * by International Business Machines Inc. "AS IS" without any warranty
- * of any kind including the warranty of merchantability or fitness
- * for a particular purpose.
- *
- *
- * This is free software. Feel free to redistribute and/or modify it.
- * Please send us e-mail and let us know if you have any problems
- * or suggestions.
- *
- * Arindam Banerji
- * axb@cse.nd.edu
- *
- *
- */
-
-
- // rtti.h
- // This file includes the definition of the RTTI interface as specified
- // by Stousroup. The implementation is portable to any compiler. If
- // your compiler supports exceptions, then define the variable exceptions
- // thru a -DEXCEPTIONS clause to your preprocessor. The additional
- // implementation information for this may be found in rttiimpl.h. The
- // actual implementation code may be found in rtti.c in the source
- // directory. Additions to this to support dynamic modification of type
- // type information, will be added later on.
-
- #include <string.h>
-
- #ifndef _KERNEL
- #include <stdlib.h>
- #endif // _KERNEL
- /***********
- BASIC RTTI INTERFACE
- **********/
-
- // The following are the macro definitions that form the RTTI interface
- #define static_type_info(T) T::info()
- #define ptr_type_info(p) ((p)->get_info())
- #define ref_type_info(r) ((r).get_info() )
-
- #define GET_PTR_INFO(p) ((p->get_info()).get_type_info())
- #define GET_TYPE_INFO(T) ((T::info()).get_type_info())
- #define GET_TYPE_INFO_2(N,I1,I2) ((N<I1,I2>::info()).get_type_info())
- #define GET_TYPE_INFO_3(N,I1,I2,I3) ((N<I1,I2,I3>::info()).get_type_info())
-
- /*
- #define ptr_cast(T,p) \
- (((T::info()).get_type_info())->can_cast(((p)->get_info()).get_type_info())\
- ? (void *) (p) : 0) \
- */
-
-
- #define ptr_cast(T,p) \
- ((GET_TYPE_INFO(T))->can_cast(GET_PTR_INFO(p)) ? (void *) p : 0 ) \
-
- #define ptr_cast_2(N,I1,I2,p) \
- ((GET_TYPE_INFO_2(N,I1,I2))->can_cast(GET_PTR_INFO(p)) ? (void *) p : 0 ) \
-
- #define ptr_cast_3(N,I1,I2,I3,p) \
- ((GET_TYPE_INFO_3(N,I1,I2,I3))->can_cast(GET_PTR_INFO(p)) ? (void *)p : 0) \
-
-
- #ifdef EXCEPTIONS
- // use this part only if your compiler supports exceptions
- class Bad_cast {
- public :
- Bad_cast(const char *p) : tn(p) { } ;
- const char *cast_to() { return tn ; } ;
- private :
- const char *tn ;
- } ; // specification for the exception class that handles inproper ref. casts
-
- #define ref_cast(T,r) \
- (T::info()->can_cast((r).get_info()) \
- ? 0 : throw Bad_cast(T::info()->name()), (T&) (r) )
-
- #endif // EXCEPTIONS handled by the compiler
-
-
- /************
- CLASS DEFINITIONS FOR RTTI INTERFACE
- ************/
-
- // This class is used to separate the implmentation of the Type_info class
- // from its use. Thus, most of the macros may be reused, even if the imple-
- // mentation of the Type_info class changes.
- class typeid {
- friend class Type_info ; // Let the Type_info class have access
- public :
- typeid (const Type_info *p) : id(p) { } ; // just hold a pointer
- const Type_info *get_type_info ( ) const
- { return id ; } ;
- int operator== (typeid ) const ;
- private :
- const Type_info *id ;
- } ; // specfication for the typeid class
-
- extern int class_count ;
-
- // This rightfully does not belong in this file, but due to the recursive
- // nature of the rtti stuff, it has to be put in this file.
- class CLASS
- {
- public :
- CLASS() { } ;
- virtual ~CLASS () { } ;
- // scaffolding that is a prt of every RTTI user class
- static const hndl_recursion info_obj ;
- virtual typeid get_info() const ;
- static typeid info() ;
- virtual void *get_this_ptr(void) const { return (void *)this ; }
- } ;
-
- class base_iterator ; // a forward declaration to keep compilers happy
-
- // The following is the main class of the RTTI interface. It supports most
- // of the member functions needd to support the interface. In addition, it
- // itself uses the scaffolding necessary to generate run-time type
- // information. Hence, it itself may be inherited from to add more
- // functionality.
-
- class Type_info : public virtual CLASS {
- friend class base_list ;
- public :
- Type_info ( const char *name, const Type_info *bases[] )
- : n(name), b(bases)
- { } ;
- virtual ~Type_info()
- { }
- const char *name () const { return n ; } ;
- base_iterator bases(int direct= 0 ) const ;
- int same ( const Type_info *p) const
- { return ((this == p ) || (strcmp(n,p->n) == 0 )) ; }
- int has_base (const Type_info *, int direct = 0 ) const ;
- int can_cast ( const Type_info *p) const
- { return (same(p) || p->has_base(this)) ; }
-
- // scaffolding that is a prt of every RTTI user class, including this one
- static const Type_info info_obj ;
- virtual typeid get_info() const ;
- static typeid info() ;
- static Type_info *_narrow(CLASS *) ;
- virtual void *get_this_ptr(void) const ;
- #ifndef _KERNEL
- void display(void) const { cerr << n << endl ; }
- #endif // _KERNEL
- private :
- const char *n ; // name of the class
- const Type_info **b ; // list of bases
- } ; // end of the Type_info class specification
-
- // The base iterator is used to loop thru the various bases of a class. This
- // list of base if set up with the direct set, then lists only the direct
- // base classes - otherwise, it lists all the base classes.
- class base_iterator {
- public :
- const Type_info *operator() () ;
- void reset () { i = 0 ; } ;
- base_iterator ( const Type_info **b, int direct = 0 ) ;
- ~base_iterator() ;
- private :
- short i ;
- short alloc ;
- const Type_info **b ;
- } ; // implementation specific base_iterator class specification
-
- #endif // _H_RTTI
-